// $Id: buffer.h 55 2011-04-23 07:00:24Z cedric.shih@gmail.com $
/*
 * Copyright (C) 2011 Cedric Shih <cedric.shih@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifndef NIOBUFFER_H_
#define NIOBUFFER_H_

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __GNUC__
#define NIOBUFFER_CHECK_FMT(a,b) __attribute__((format(printf, a, b)))
#else
#define NIOBUFFER_CHECK_FMT(a,b)
#endif

#include <sys/types.h>

struct niobuffer;

struct niobuffer *niobuffer_new(size_t capacity);

void niobuffer_free(struct niobuffer *buffer);

struct niobuffer *niobuffer_clone(struct niobuffer *buffer);

struct niobuffer *niobuffer_slice(struct niobuffer *buffer,
		size_t position, size_t capacity);

struct niobuffer *niobuffer_wrapper(void);

int niobuffer_wrap(struct niobuffer *buffer, struct niobuffer *target);

int niobuffer_resize(struct niobuffer *buffer, size_t capacity);

int niobuffer_get(struct niobuffer *buffer, int *b);

int niobuffer_gets(struct niobuffer *buffer, unsigned char *data, size_t len);

int niobuffer_skip(struct niobuffer *buffer, size_t offset);

int niobuffer_put(struct niobuffer *buffer, int b);

int niobuffer_puts(struct niobuffer *buffer,
		const unsigned char *data, size_t len);

int niobuffer_putf(struct niobuffer *buffer,
		const char *fmt, ...) NIOBUFFER_CHECK_FMT(2,3);

struct niosocket;

int niobuffer_read(struct niobuffer *buffer, struct niosocket *socket);

int niobuffer_write(struct niobuffer *buffer, struct niosocket *socket);

int niobuffer_load(struct niobuffer *buffer, struct niobuffer *source);

unsigned char *niobuffer_array(struct niobuffer *buffer);

size_t niobuffer_capacity(struct niobuffer *buffer);

size_t niobuffer_position(struct niobuffer *buffer);

int niobuffer_set_position(struct niobuffer *buffer, size_t position);

size_t niobuffer_limit(struct niobuffer *buffer);

int niobuffer_set_limit(struct niobuffer *buffer, size_t limit);

size_t niobuffer_remaining(struct niobuffer *buffer);

void niobuffer_clear(struct niobuffer *buffer);

void niobuffer_flip(struct niobuffer *buffer);

void niobuffer_rewind(struct niobuffer *buffer);

void niobuffer_mark(struct niobuffer *buffer);

void niobuffer_reset(struct niobuffer *buffer);

int niobuffer_compact(struct niobuffer *buffer);

enum niobuffer_event_type {
	NIO_BUFFER_EVENT_WRITTEN,
	NIO_BUFFER_EVENT_RELEASING,
	NIO_BUFFER_EVENT_REPLACING,
};

struct niobuffer_event {
	enum niobuffer_event_type type;
	union {
		struct {
			size_t old;
			size_t new;
		} position;
	} data;
};

typedef void (*niobuffer_cb)(struct niobuffer *buffer,
		struct niobuffer_event *event, void *arg);

void niobuffer_set_cb(struct niobuffer *buffer,
		niobuffer_cb cb, void *cbarg);

#ifdef __cplusplus
}
#endif

#endif /* NIOBUFFER_H_ */
